package util;
import java.security.SecureRandom;
import java.util.StringTokenizer;

public class IdGeneratorUtil {

    private final static long beginTs = 1638876354885L;

    private long lastTs = 0L;

    private long processId;
    private int processIdBits = 10;

    private long sequence = 0L;
    private int sequenceBits = 12;

    public IdGeneratorUtil() {
        processId = new SecureRandom().nextInt(((1 << processIdBits) - 1));
        String address = "127.0.0.1";
        StringTokenizer tokenizer = new StringTokenizer(address, ".");
        while (tokenizer.hasMoreTokens()) {
            String token = tokenizer.nextToken();
            if (!tokenizer.hasMoreTokens()) {
                processId = Integer.parseInt(token);
            }
        }
        if (processId > ((1 << processIdBits) - 1)) {
            throw new RuntimeException("进程ID超出范围，设置位数" + processIdBits + "，最大"
                    + ((1 << processIdBits) - 1));
        }
        this.processId = processId;
    }

    protected long timeGen() {
        return System.currentTimeMillis();
    }

    public synchronized long nextId() {
        long ts = timeGen();
        if (ts < lastTs) {
            throw new RuntimeException("时间戳顺序错误");
        }
        if (ts == lastTs) {
            sequence = (sequence + 1) & ((1 << sequenceBits) - 1);
            if (sequence == 0) {
                ts = nextTs(lastTs);
            }
        } else {
            sequence = 0L;
        }
        lastTs = ts;
        return ((ts - beginTs) << (processIdBits + sequenceBits)) | (processId << sequenceBits)
                | sequence;
    }

    protected long nextTs(long lastTs) {
        long ts = timeGen();
        while (ts <= lastTs) {
            ts = timeGen();
        }
        return ts;
    }

    public static void main(String[] args) {
        int i = 8 << 2;
        System.out.println(i);
    }
}
